package com.hn658.base.message.itf.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hn658.base.message.account.entity.AccountUserInfoEO;
import com.hn658.base.message.account.exception.AccountException;
import com.hn658.base.message.account.service.IAccountUserManagerService;
import com.hn658.base.message.common.contants.MessageContants;
import com.hn658.base.message.common.enums.EventPriority;
import com.hn658.base.message.common.enums.EventType;
import com.hn658.base.message.eventbus.event.groupchat.GroupMsgEvent;
import com.hn658.base.message.eventbus.event.singlechat.SingleMsgEvent;
import com.hn658.base.message.eventbus.event.systemchat.SystemMsgEvent;
import com.hn658.base.message.group.business.IGroupManager;
import com.hn658.base.message.group.entity.GroupEO;
import com.hn658.base.message.group.entity.MemberEO;
import com.hn658.base.message.group.exception.GroupException;
import com.hn658.base.message.itf.IManagerService;
import com.hn658.base.message.itf.define.enums.ResponseCode;
import com.hn658.base.message.itf.dto.GroupDTO;
import com.hn658.base.message.itf.dto.ItfGroupMessageRequest;
import com.hn658.base.message.itf.dto.ItfGroupResponseResult;
import com.hn658.base.message.itf.dto.ItfQueryMessageRequest;
import com.hn658.base.message.itf.dto.ItfQueryMessageResponse;
import com.hn658.base.message.itf.dto.ItfSendMessageRequest;
import com.hn658.base.message.itf.dto.ItfUserResponseResult;
import com.hn658.base.message.itf.dto.MemberDTO;
import com.hn658.base.message.itf.dto.MessageDTO;
import com.hn658.base.message.notification.msg.business.IMessageManager;
import com.hn658.base.message.notification.msg.dto.MsgQueryDTO;
import com.hn658.base.message.notification.msg.entity.MessageEO;
import com.hn658.base.message.publish.business.IEventPublishManager;
import com.hn658.framework.cache.message.MessageCache;
import com.hn658.framework.dataaccess.pagination.GenericPage;
import com.hn658.framework.shared.exception.BusinessException;
import com.hn658.framework.shared.utils.BeanMapper;
import com.hn658.framework.shared.utils.UUIDUtils;


/**
 * 
 * 消息服务
 * @author ztjie
 * @date 2015-11-3 上午10:02:04
 * @since
 * @version
 */
@Service
public class MessageServiceImpl implements IManagerService {
	
	@Autowired
	private IAccountUserManagerService accountUserManagerService;

	@Autowired
	private IEventPublishManager eventPublishManager;
	
	@Autowired
	private IGroupManager groupManager;
	
	@Autowired
	private MessageCache messageCache;
	
	@Autowired
	private IMessageManager messageManager;
	
	@Override
	public ItfUserResponseResult getToken(String appKey, String userId, String name,
			String portraitUri) {
		ItfUserResponseResult result = new ItfUserResponseResult();
		try{
			String token = accountUserManagerService.createToken(appKey, userId, name, portraitUri);
			result.setUserId(userId);
			result.setToken(token);
			result.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
			result.setCode(ResponseCode.IsException);
			result.setMessage(messageCache.getMessage(e.getErrorCode()));
		}
		return result;
	}

	
	@Override
	public ItfUserResponseResult updateAccount(String appKey, String userId,
			String name, String portraitUri) {
		ItfUserResponseResult result = new ItfUserResponseResult();
		try{
		    AccountUserInfoEO oldUser = accountUserManagerService.findAccountByAppIdUid(appKey, userId);
		   if(oldUser==null){
			   throw new AccountException(AccountException.AccountEmpty);
		   }
		    AccountUserInfoEO user = new AccountUserInfoEO();
		    user.setId(oldUser.getId());
		    if(StringUtils.isNotBlank(name)){
		    	user.setNickName(name);
		    }
		    if(StringUtils.isNotBlank(portraitUri)){
		    	user.setAvatarURL(portraitUri);
		    }
		    user.setLastUpdateTime(new Date());
		    accountUserManagerService.updateAccount(user);
		    result.setCode(ResponseCode.IsSuccess);
        }catch(BusinessException e){
    	    result.setCode(ResponseCode.IsException);
    	    result.setMessage(messageCache.getMessage(e.getErrorCode()));
        }
	    return result;
	}

	@Override
	public ItfUserResponseResult sendSingleMessage(ItfSendMessageRequest request) {
		ItfUserResponseResult result = new ItfUserResponseResult();
		MessageEO message=new MessageEO();
       try{
			message.setCreateTime(new Date());
	        message.setDeleted(false);
	        message.setFromUid(MessageContants.SYSTEM_USER_ID);
	        message.setMsg(request.getMsg());
	        message.setMsgType(request.getMsgType());
	        message.setAppId(request.getAppId());
	        //message.setToDeviceId(null);
	        message.setToUid(request.getToUid());
	        message.setUuid(UUIDUtils.getUUID());
	        SingleMsgEvent event=new SingleMsgEvent();
	        event.setAppId(request.getAppId());
	        event.setEventId(UUIDUtils.getUUID());
	        event.setType(EventType.NormalSingleChat);
	        event.setMessage(message);
	        event.setPriority(EventPriority.getPriorityByValue(request.getEvenPriority()));
	        event.setIsNeedSave(request.getIsNeedSave());
	        event.setIsOfflineSend(request.getOfflineMsg());
	        eventPublishManager.publishSingleMsgEvent(event);
	        result.setCode(ResponseCode.IsSuccess);
       }catch(BusinessException e){
    	   result.setCode(ResponseCode.IsException);
    	   result.setMessage(messageCache.getMessage(e.getErrorCode()));
       }
	   return result;
	}

	@Override
	public ItfUserResponseResult sendGroupMessage(ItfSendMessageRequest request) {
		ItfUserResponseResult result = new ItfUserResponseResult();
		MessageEO message=new MessageEO();
       try{
			message.setCreateTime(new Date());
	        message.setDeleted(false);
	        message.setFromUid(MessageContants.SYSTEM_USER_ID);
	        message.setMsg(request.getMsg());
	        message.setMsgType(request.getMsgType());
	        message.setAppId(request.getAppId());
	        message.setToGroupId(request.getToGroupId());
	        message.setUuid(UUIDUtils.getUUID());
	        GroupMsgEvent event=new GroupMsgEvent();
	        event.setAppId(request.getAppId());
	        event.setEventId(UUIDUtils.getUUID());
	        event.setType(EventType.NormalGroupChat);
	        event.setMessage(message);
	        event.setPriority(EventPriority.getPriorityByValue(request.getEvenPriority()));
	        event.setIsNeedSave(request.getIsNeedSave());
	        event.setIsOfflineSend(request.getOfflineMsg());
	        eventPublishManager.publishGroupMsgEvent(event);
	        result.setCode(ResponseCode.IsSuccess);
       }catch(BusinessException e){
    	   result.setCode(ResponseCode.IsException);
    	   result.setMessage(messageCache.getMessage(e.getErrorCode()));
       }
       return result;
	}

	
	
	@Override
	public ItfUserResponseResult sendSystemMessage(ItfSendMessageRequest request) {
		ItfUserResponseResult result = new ItfUserResponseResult();
		MessageEO message=new MessageEO();
       try{
			message.setCreateTime(new Date());
	        message.setDeleted(false);
	        message.setFromUid(MessageContants.SYSTEM_USER_ID);
	        message.setMsg(request.getMsg());
	        message.setMsgType(request.getMsgType());
	        message.setAppId(request.getAppId());
	        message.setUuid(UUIDUtils.getUUID());
	        SystemMsgEvent event=new SystemMsgEvent();
	        if(request.getToUid()!=null){
	        	message.setToUid(request.getToUid());
	        	event.setIsPerson(true);
	        }
	        event.setAppId(request.getAppId());
	        event.setEventId(UUIDUtils.getUUID());
	        event.setType(EventType.SystemChat);
	        event.setMessage(message);
	        event.setPriority(EventPriority.getPriorityByValue(request.getEvenPriority()));
	        event.setIsNeedSave(false);
	        event.setIsOfflineSend(true);
	        eventPublishManager.publishSystemMsgEvent(event);
	        result.setCode(ResponseCode.IsSuccess);
       }catch(BusinessException e){
    	   result.setCode(ResponseCode.IsException);
    	   result.setMessage(messageCache.getMessage(e.getErrorCode()));
       }
       return result;
	}


	@Override
	public ItfGroupResponseResult createGroup(ItfGroupMessageRequest request) {
		ItfGroupResponseResult result = new ItfGroupResponseResult();
		GroupEO group = new GroupEO();
		try{
			if(StringUtils.isBlank(request.getAppId())){
				throw new GroupException(GroupException.EmptyAppId);
			}
			group.setAppId(request.getAppId());
			if(request.getUid()==null){
				throw new GroupException(GroupException.EmptyCreateUid);
			}
			group.setCreateUid(request.getUid());
			group.setAvaUrl(request.getAvaUrl());
			group.setGroupName(request.getGroupName());
			group.setGroupIntro(request.getGroupIntro());
			if(request.getGroupType()!=null){
				group.setGroupType(1);
			}else {
				group.setGroupType(request.getGroupType());
			}
			GroupEO createGroup = groupManager.createGroup(group, request.getNickName());
			GroupDTO groupDto = new GroupDTO();
			if(createGroup!=null){
				BeanUtils.copyProperties(createGroup, groupDto);
			}
			result.setGroup(groupDto);
			result.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
	    	   result.setCode(ResponseCode.IsException);
	    	   result.setMessage(messageCache.getMessage(e.getErrorCode()));
       }
	   return result;
	}

	@Override
	public ItfGroupResponseResult joinGroup(String appId, Long groupId,
			String uid, String nickName) {
		ItfGroupResponseResult result = new ItfGroupResponseResult();
		try{
			groupManager.joinGroup(appId, groupId, uid);
			result.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
	    	   result.setCode(ResponseCode.IsException);
	    	   result.setMessage(messageCache.getMessage(e.getErrorCode()));
	    }
		return result;
	}

	@Override
	public ItfGroupResponseResult modifyGroupInfo(ItfGroupMessageRequest request) {
		ItfGroupResponseResult result = new ItfGroupResponseResult();
		try{
			if(StringUtils.isBlank(request.getAppId())){
				throw new GroupException(GroupException.EmptyAppId);
			}
			if(request.getGroupId()==null){
				throw new GroupException(GroupException.EmptyGroupId);
			}
			GroupEO groupById = groupManager.findGroup(request.getAppId(), request.getGroupId());
			if(groupById==null){
				throw new GroupException(GroupException.EmptyGroup);
			}
			if(StringUtils.isBlank(request.getGroupName())){
				groupById.setGroupName(request.getGroupName());
			}
			if(StringUtils.isBlank(request.getAvaUrl())){
				groupById.setAvaUrl(request.getAvaUrl());
			}
			if(StringUtils.isBlank(request.getGroupIntro())){
				groupById.setGroupIntro(request.getGroupIntro());
			}
			groupManager.updateGroup(groupById);
			result.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
	    	   result.setCode(ResponseCode.IsException);
	    	   result.setMessage(messageCache.getMessage(e.getErrorCode()));
	    }
		return result;
	}

	@Override
	public ItfGroupResponseResult exitGroup(String appId, Long groupId, String uid) {
		ItfGroupResponseResult result = new ItfGroupResponseResult();
		try{
			groupManager.exitTheGroup(appId, groupId, uid);
			result.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
	    	   result.setCode(ResponseCode.IsException);
	    	   result.setMessage(messageCache.getMessage(e.getErrorCode()));
	    }
		return result;
	}

	@Override
	public ItfGroupResponseResult disbandGroups(String appId, Long groupId,
			String uid) {
		ItfGroupResponseResult result = new ItfGroupResponseResult();
		try{
			groupManager.disbandGroups(appId, groupId, uid);
			result.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
	    	   result.setCode(ResponseCode.IsException);
	    	   result.setMessage(messageCache.getMessage(e.getErrorCode()));
	    }
		return result;
	}

	@Override
	public ItfQueryMessageResponse queryMessage(ItfQueryMessageRequest request) {
		ItfQueryMessageResponse response = new ItfQueryMessageResponse();
		try{
			MsgQueryDTO query = new MsgQueryDTO();
			query.setAppId(request.getAppId());
			query.setFromUid(request.getUid());
			query.setToUid(request.getToUid());
			if(StringUtils.isNotBlank(request.getOrderBy())){
				query.setOrderBy(request.getOrderBy());
			}
			if(request.getStart()!=null){
				query.setStart(request.getStart());
			}
			if(request.getPageSize()!=null){
				query.setPageSize(request.getPageSize());
			}
			GenericPage<MessageEO> data = messageManager.querySinglePage(query);
			List<MessageDTO> msgList = null;
			if(data.getData()!=null){
				msgList = BeanMapper.mapList(data.getData(), MessageDTO.class);
			}
			response.setMsgList(msgList);
			response.setTotalCount(data.getTotalCount());
			response.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
			response.setCode(ResponseCode.IsException);
			response.setMessage(messageCache.getMessage(e.getErrorCode()));
	    }
		return response;
	}

	@Override
	public ItfQueryMessageResponse queryGroupMessage(ItfQueryMessageRequest request) {
		ItfQueryMessageResponse response = new ItfQueryMessageResponse();
		try{
			MsgQueryDTO query = new MsgQueryDTO();
			query.setAppId(request.getAppId());
			query.setFromUid(request.getUid());
			query.setToGroupId(request.getGroupId());
			if(StringUtils.isNotBlank(request.getOrderBy())){
				query.setOrderBy(request.getOrderBy());
			}
			if(request.getStart()!=null){
				query.setStart(request.getStart());
			}
			if(request.getPageSize()!=null){
				query.setPageSize(request.getPageSize());
			}
			GenericPage<MessageEO> data = messageManager.queryGroupPage(query);
			List<MessageDTO> msgList = null;
			if(data.getData()!=null){
				msgList = BeanMapper.mapList(data.getData(), MessageDTO.class);
			}
			response.setMsgList(msgList);
			response.setTotalCount(data.getTotalCount());
			response.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
			response.setCode(ResponseCode.IsException);
			response.setMessage(messageCache.getMessage(e.getErrorCode()));
	    }
		return response;
	}
	
	@Override
	public ItfGroupResponseResult queryMemberByGroup(String appId, Long groupId) {
		ItfGroupResponseResult result = new ItfGroupResponseResult();
		try{
			List<MemberEO> memberList = groupManager.queryGroupMemberList(appId, groupId);
			List<MemberDTO> memberLists = new ArrayList<MemberDTO>();
			for(MemberEO memberEO: memberList){
				MemberDTO dto = new MemberDTO();
				BeanUtils.copyProperties(memberEO, dto);
				memberLists.add(dto);
			}
			result.setMemberList(memberLists);
			result.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
			result.setCode(ResponseCode.IsException);
			result.setMessage(messageCache.getMessage(e.getErrorCode()));
	    }
		return result;
	}

	@Override
	public ItfGroupResponseResult queryMemberByGroup(String appId,
			Long groupId, Integer pageSize, Integer index) {
		ItfGroupResponseResult result = new ItfGroupResponseResult();
		try{
			int limit=10;
			int start=0;
			if(pageSize!=null){
				limit =  pageSize;
			}
			if(index!=null){
				start = index;
			}
			GenericPage<MemberEO> memberList = groupManager.queryGroupMembers(appId, groupId, limit, start,"id",false);
			List<MemberDTO> memberLists = new ArrayList<MemberDTO>();
			for(MemberEO memberEO: memberList.getData()){
				MemberDTO dto = new MemberDTO();
				BeanUtils.copyProperties(memberEO, dto);
				memberLists.add(dto);
			}
			result.setMemberList(memberLists);
			result.setTotalCount(memberList.getTotalCount());
			result.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
			result.setCode(ResponseCode.IsException);
			result.setMessage(messageCache.getMessage(e.getErrorCode()));
	    }
		return result;
	}

	@Override
	public ItfGroupResponseResult numberMemberByGroup(String appId, Long groupId) {
		ItfGroupResponseResult result = new ItfGroupResponseResult();
		try{
			int number = groupManager.numMemberByGroup(appId, groupId);
			result.setTotalCount(Long.valueOf(number));
			result.setCode(ResponseCode.IsSuccess);
		}catch(BusinessException e){
			result.setCode(ResponseCode.IsException);
			result.setMessage(messageCache.getMessage(e.getErrorCode()));
	    }
		return result;
	}
	
	
}
